/* Octopus PDF - A simple document viewer for Android.
   Copyright (C) 2013  Gerald Thaler

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
package de.geraldthaler.octopuspdf.util;

/**
 * @author Gerald Thaler
 */
public final class Threading {
    public static void sleepUninterruptibly(long time) {
        if (time <= 0)
            return;
        final long maxTime = 1000000000000L;
        if (time > maxTime)
            time = maxTime; // avoids overflow
        long now = System.nanoTime();
        final long sleepUntil = now + 1000000L * time; 
        boolean interrupted = false;
        try {
            for (;;) {
                long duration = (sleepUntil - now) / 1000000L;
                if (duration <= 0)
                    break;
                try {
                    Thread.sleep(duration);
                } catch (final InterruptedException e) {
                    interrupted = true;
                }
                now = System.nanoTime();
            }
        } finally {
            if (interrupted)
                Thread.currentThread().interrupt();
        }
    }

    public static void joinUninterruptibly(final Thread thread) {
        boolean interrupted = false;
        try {
            for (;;) {
                try {
                    thread.join();
                    break;
                } catch (final InterruptedException e) {
                    interrupted = true;
                }
            }
        } finally {
            if (interrupted)
                Thread.currentThread().interrupt();
        }
    }

    public static void waitUninterruptibly(final Object object) {
        boolean interrupted = false;
        try {
            for (;;) {
                try {
                    object.wait();
                    break;
                } catch (final InterruptedException e) {
                    interrupted = true;
                }
            }
        } finally {
            if (interrupted)
                Thread.currentThread().interrupt();
        }
    }

    private Threading() {
        // no instances
    }
}
